home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / program / 177 / c / mwtodri.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-09-15  |  6.3 KB  |  257 lines

  1. /*
  2.     mwtodr.c
  3.  a program to convert from MWC format executables to
  4.  DRI format executables. Rearranges things and convert the the symbol table
  5.  entries.
  6.  
  7. All right reserved David DeGeorge September 5,1987.
  8. This program and it's source may be freely distributed on a not for profit
  9. basis only
  10. */
  11.  
  12.  
  13.  
  14. #include <nout.h>
  15. #include <gemout.h>
  16. #include <stdio.h>
  17. #include <canon.h>
  18.  
  19. /* usefuls */
  20. #define min(a,b) ( a > b ? b : a)
  21. #define READ 0
  22. #define WRITE 1
  23.  
  24. /* defines for flag conversion */
  25. #define DEFINED 0x8000
  26. #define GLOBAL 0x2000
  27. #define DATABASED 0x400
  28. #define TEXTBASED 0x200
  29. #define BSSBASED 0x100
  30.  
  31. char copyright[] = "Copyright 1987 David DeGeorge";
  32. char mwccopyr[] = "Portions of the program copyright 1984 Mark Williams Co.";
  33. /* some constants */
  34. #define BIGBUF 512*32   /* a biggish buffer make it bigger goes faster */
  35. #define NSYM 300    /* number of symbols to do at a wack */
  36. #define SMW sizeof(struct ldsym)    /* 22 MWC symbols */
  37. #define SGM sizeof(struct gemsym)   /* 14 DRI symbols */
  38. long _stksize=4000L;   /* to be safe registers get saved on our stack */
  39.  
  40. /* our globals */
  41. char * buffer;
  42. struct gemohdr gemhead;
  43. struct ldsym *cymbals;
  44. struct ldheader marky;
  45. struct gemsym *gsyms;
  46. long look40();
  47.  
  48.    main ( argc,argv)
  49.    int argc;
  50.    char ** argv;
  51.    {
  52.        int     infd,        /* file descriptors */
  53.             outfd;
  54.         long     syms,        /* counters */
  55.                  nsyms,
  56.                nreloc = 4L;
  57.        char     msg[80];    /* for messages */
  58.        
  59.    /* check to see if enuff arguments and if there are ok */
  60.           if ( argc != 3) usage();
  61.        if(strcmp(argv[1],argv[2])== 0 ) 
  62.         abort("Infile and outfile must be different\n\r");
  63.         
  64.    /* allocate space for the buffers */
  65.        if ( ( buffer = malloc(BIGBUF) ) == (char *) 0 ){
  66.             sprintf(msg,"Can't allocate %d  bytes\n\r",BIGBUF);
  67.             abort(msg);
  68.         }
  69.        if ( (cymbals = malloc(NSYM*SMW )) == (char *) 0 ){
  70.             sprintf(msg,"Can't allocate for symbols");
  71.             abort(msg);
  72.         }
  73.         
  74.        if ( ( gsyms = malloc(NSYM*SGM )) == (char *) 0 ){
  75.             sprintf(msg,"Can't allocate for symbols\n\r");
  76.             abort(msg);
  77.         }
  78.     
  79.    /* open the input file and check to see if executable and
  80.        then if MWC format */        
  81.        if ( (infd = open(argv[1],READ)) < 0 ){
  82.            sprintf(msg,"Can't open %s for reading\n\r",argv[1]);
  83.            abort(msg);
  84.        }
  85.           read( infd,&gemhead,sizeof(gemhead));
  86.            if ( gemhead.g_magic != GEMOMAGIC ) {
  87.                sprintf(msg,"%s is the wrong format\n\r",argv[1]);
  88.                abort(msg);
  89.        }
  90.        
  91.       /* create the output file */
  92.              creat(argv[2],1);
  93.           if ( ( outfd = open(argv[2],WRITE)) < 0) {
  94.            sprintf(msg,"Can't open %s for writing\n\r",argv[2]);
  95.            abort(msg);
  96.        }
  97.        /* write out the header */
  98.         write(outfd,&gemhead,sizeof(gemhead));
  99.        
  100.    /* calculate the amount of space used by the header,text and data segements
  101.        and copy them to the new file */
  102.        syms = gemhead.g_ssize[GO_TEXT] + gemhead.g_ssize[GO_DATA];
  103.         xfer(outfd,infd,syms);    
  104.         
  105.    /* calculate the number of relocation bytes..
  106.     a long followed by bytes until the first 0 */
  107.     
  108.           read(infd,buffer,4);
  109.      nreloc += look40(infd);  /* look for the zero */
  110.      
  111.    /* seek to the MWC header and read it */
  112.     lseek( infd,syms+sizeof(gemhead)+nreloc,0);           
  113.     read (infd,&marky,sizeof(marky));
  114.     if ( _canw(marky.l_magic) != L_MAGIC) {
  115.         sprintf(msg,"%s is not a MWC executable\n\r",argv[1]);
  116.         unlink(argv[2]);
  117.         abort(msg);
  118.     }      
  119.     
  120.    /*  next do the symbols */
  121.       nsyms = _canl(marky.l_ssize[L_SYM])/sizeof(struct ldsym);
  122.       gemhead.g_ssize[GO_SYM] = nsyms * sizeof(struct gemsym);
  123.       convrt(infd,outfd,nsyms);
  124.       
  125. /* write out the relocation bytes */
  126.           syms = sizeof(gemhead);  
  127.        syms += gemhead.g_ssize[GO_TEXT] + gemhead.g_ssize[GO_DATA];          
  128.       lseek(infd,syms,0);
  129.       xfer(outfd,infd,nreloc);
  130.       
  131.   /* fix up the header to show the new sizeof the symbols */      
  132.     lseek(outfd,0L,0);
  133.     write(outfd,&gemhead,sizeof(gemhead));
  134.     
  135. convrt(in,out,n)
  136. int in,out;
  137. long n;
  138.  
  139.  
  140. {  
  141.           long     todo=n;
  142.       int     temp,
  143.           flag,
  144.           did,
  145.           t1;
  146.       char msg[80];
  147.           register int     i,
  148.                   j;
  149.           register char *p,
  150.                   *q;
  151.           register struct gemsym *g;
  152.           register struct ldsym  *l;
  153.  
  154.           while ( todo > 0) {
  155.                t1 = min(todo,NSYM);
  156.             if((did = read(in,cymbals,t1*SMW)) < 0)
  157.                 abort("Read error in convrt\r\n");
  158.               t1=did/SMW;
  159.               j=t1;
  160.               l=cymbals;
  161.               g=gsyms;
  162.               while( j-- > 0 ){
  163.                    flag = _canw(l->ls_type);
  164.                    p = g->gs_name;
  165.                    q = l->ls_id;
  166.                    for ( i=0 ; i < 8 ; i++,p++,q++)*p=*q;
  167.               g->gs_value = _canl(l->ls_addr);
  168.               temp = DEFINED;
  169.              if ( flag & 020 ) temp |= GLOBAL;
  170.               switch( flag & 0xf ) {
  171.                 case L_SHRI:
  172.                 case L_PRVI:
  173.                 case L_BSSI:
  174.                     temp |= TEXTBASED;
  175.                     break;
  176.                 case L_SHRD:
  177.                 case L_PRVD:
  178.                     temp |= DATABASED;
  179.                     break;
  180.                 case L_BSSD:
  181.                     temp |= BSSBASED;
  182.                     break;
  183.                 default:
  184.                     sprintf(msg,
  185.                     "I don't recognize flag %d\r\n",
  186.                     flag & 0xF);
  187.                       write(2,msg,strlen(msg));
  188.                  break;
  189.             }
  190.          g -> gs_type = temp;
  191.           l++;
  192.           g++;
  193.     }
  194.     if( write(out,gsyms,t1*SGM) < 0){
  195.             perror("");
  196.             abort("Write error in cnvrt\r\c");
  197.         }
  198.     todo -= t1;
  199.      }
  200.  
  201. }
  202. xfer(out,in,n)
  203. int in,out;
  204. long n;
  205.  
  206. {   
  207.     register int did;
  208.     register long todo=n;
  209.     
  210.         while( todo > 0L ) {
  211.         if((did = read(in,buffer,(int)min(todo,BIGBUF)))<0){
  212.             perror("");
  213.             abort("Read failure\r\n");
  214.         }
  215.             if (write(out,buffer,did) != did ){
  216.                 perror("");
  217.                 abort("Write failure\n\r");
  218.             }
  219.             todo -= did;
  220.         }
  221. }
  222.  usage()
  223.  {
  224.    char *msg="Usage mwcfile drifile\n\r";
  225.    write(2,msg,strlen(msg));
  226.    exit(1);
  227. }
  228.  
  229. abort(msg)
  230. char * msg;
  231. {
  232.     write(2,msg,strlen(msg));
  233.     exit(1);
  234. }
  235.  
  236.  
  237. long look40(in)   /* look for a zero 
  238.             will leave the file pointer in the wrong place */
  239. int in;
  240. {       register long temp=0L;
  241.      register char *p,*q;
  242.        q = buffer + BIGBUF;
  243.     while ( read(in,buffer,BIGBUF) > 0){
  244.         p=buffer;
  245.     for( p=buffer; p < q ; p++) {
  246.        temp++; 
  247.        if( *p == '\0') goto end ;
  248.        }
  249.  
  250. }
  251. end:
  252.  
  253.     return(temp);
  254.       
  255. }
  256.